package entities;

import entities.exceptions.MissingRouteException;
import entities.exceptions.EmptyRouteException;
import entities.exceptions.RouteIndexOutOfRangeException;
import java.awt.Image;
import static entities.Actions.WorkerActions.*;

/**
 * Worker Class
 * @author mateusz
 */
public class Worker extends TransportRobot {

    /**
     * route to new supply
     */
    protected Route newRoute;
    /**
     * reference to route from factory
     */
    protected Route routeCopy;
    
    /**
     * if supply was empty
     */
    protected boolean emptySupply;

    
    /**
     * Creates Worker
     * @param factory       factory-mother
     * @param defaultImage  image
     * @param myName        name
     */
    public Worker(Factory factory, Image defaultImage, String myName) {
        super(factory, defaultImage, myName);
       
        this.currentSupply = factory.getExtractedSupply();
        this.maxCapacity = 10;

        routeCopy = null;
        newRoute = null;
        
        updateProperties();
        updateLocation();
        t.start();
    }

    @Override
    protected void updateProperties() {
        super.updateProperties();
    }
    
    @Override
    public synchronized int kill(){
        super.kill();
        int units = factory.deleteWorker(this);
        units += supplyUnits;
        
        return units;
    }
    
    /**
     * Adds route to new supply
     * @param route
     */
    public void addRoute(Route route) {
        newRoute = route;
        // if start state - robot without any targets
        if (routeCopy == null) {
            addTargets();
        }
    }

    /**
     * Change route to new route
     */
    protected void changeRoute() {
        if (newRoute != null) {
            routeCopy = newRoute;
            newRoute = null;
        }
    }

    /**
     * Set targets and next route
     * If there is no new route, create from old copy
     */
    protected void addTargets() {
        changeRoute();

        Route reversedRoute = new Route(routeCopy);
        reversedRoute.reverse(); // start from supply
        try {
            reversedRoute.deleteCheckpoint(0, false);
        } catch (RouteIndexOutOfRangeException ex) {
        }

        // add route to supply and back as current
        route.appends(routeCopy);
        try {
            Tile supplyTile = routeCopy.getEnd();
            Tile factoryTile = routeCopy.getStart();

            addTarget(supplyTile, GET_SUPPLY);
            addTarget(factoryTile, GIVE_SUPPLY);

        } catch (EmptyRouteException ex) {
        }

        route.appends(reversedRoute);
        
        wakeUp();
    }

    @Override
    protected synchronized void action(Target target) {
        // in factory
        if (target.action == GIVE_SUPPLY) {
            // unload supply
            unload(this.factory, currentSupply, supplyUnits);
            
            // if back from empty supply - try set new one
            if (emptySupply) {
                while (isRunning()) {
                    try {
                        factory.newRouteForWorker(this);
                        emptySupply = false;
                        break; // break if route exists
                    } catch (MissingRouteException ex) {
                        goSleep();
                    }
                }
                if(!isRunning()){
                    return ;
                }
            }
            
            this.supplyUnits = 0;
            
            // set new targets
            addTargets();
            
            // get fuel
            getFuel(this.factory);
            
        } // in supply
        else if (target.action == GET_SUPPLY) {
            // take supplies
            Supply supply = (Supply) target.tile.getAssociatedEntity();
            // supply is empty
            if (supply == null || !(supply instanceof Supply)) {
                emptySupply = true;

            } else {
                int units = supply.takeUnits(this.maxCapacity);
                addUnits(units);
            }
        }
    }
}
